clc
clear;close all
global Y2 Y3
%% 导入数据，生成乱序数组
iris_data=readmatrix('F:\matalable文件\CNN\iris\iris_data.xlsx');         %导入数据
arry=randperm(150);
%% 划分数据
input_train = iris_data(arry(1:100),1:4)';
output_train = iris_data(arry(1:100),5)';
input_test = iris_data(arry(101:150),1:4)';
output_test = iris_data(arry(101:150),5)';
% 节点个数
input_num = 4;                    %4个特征
hidden_num = 7;                   %隐藏层神经元
output_num = 3;                   %输出类别
w1_num = input_num*hidden_num;    %输入层到隐藏层的权值个数
w2_num = output_num*hidden_num;    %隐藏层到输出层的权值个数
N = w1_num+hidden_num+w2_num+output_num;%优化变量的个数（权值加阈值）

%% 把输出1维转换为3维[1 0 0] [0 1 0] [0 0 1]
% output=zeros(100,3);
% for i=1:100
%     switch output_train(i)
%         case 1
%         output(i,:)=[1 0 0];
%         case 2
%         output(i,:)=[0 1 0];
%         case 3
%         output(i,:)=[0 0 1];
%     end
% end
output=zeros(3,100);                     %训练数据转化为三维
output2=zeros(3,50);                     %测试数据转化为三维
for i=1:100
    switch output_train(i)
        case 1
        output(:,i)=[1 0 0]';
        case 2
        output(:,i)=[0 1 0]';
        case 3
        output(:,i)=[0 0 1]';
    end
end
for i=1:50
    switch output_test(i)
        case 1
        output2(:,i)=[1 0 0]';
        case 2
        output2(:,i)=[0 1 0]';
        case 3
        output2(:,i)=[0 0 1]';
    end
end
%可以使用ind2vec函数
%% 数据归一化
method=@mapminmax;                 %最大归一化
%method=@mapstd;                    %标准归一化
[input,inputs] = method(input_train);
%[output,outputs] = method(output_train);
input_test_guiyi = method('apply',input_test,inputs);

%% 定义遗传算法参数
NIND = 40;                      % 种群大小
MAXGEN = 50;                    % 最大遗传代数
PRECI = 10;                     % 个体长度(变量二进制位数）
GGAP = 0.95;                    % 代沟
px = 0.7;                       % 交叉概率
pm = 0.01;                      % 变异概率
trace = zeros(N + 1, MAXGEN);   % 寻优结果的初始值
FieldD = [repmat(PRECI, 1, N); repmat([-0.5; 0.5], 1, N); repmat([1;0;1;1], 1, N)]; % 区域描述器
Chrom = crtbp(NIND, PRECI * N); % 创建任意离散随机种群
% 优化
gen = 0;                                                % 代计数器
X = bs2rv(Chrom, FieldD);                               % 计算初始种群的十进制转换
ObjV = Objfun(X, input, output, hidden_num, input_test_guiyi, output_test);      % 计算目标函数值(训练输入，训练输出，隐藏神经元，测试输入，测试输出）
while gen < MAXGEN
    fprintf('%d\n', gen)
    FitnV = ranking(ObjV);                              % 分配适应度值
    SelCh = select('sus', Chrom, FitnV, GGAP);          % 选择
    SelCh = recombin('xovsp', SelCh, px);               % 重组
    SelCh = mut(SelCh, pm);                             % 变异
    X = bs2rv(SelCh, FieldD);                           % 子代个体的二进制到十进制转换
    ObjVSel = Objfun(X, input, output, hidden_num, input_test_guiyi, output_test);       % 计算子代的目标函数值
    [Chrom, ObjV] = reins(Chrom, SelCh, 1, 1, ObjV, ObjVSel);   % 将子代重插入到父代，得到新种群
    X = bs2rv(Chrom, FieldD);                            % 子代个体的二进制到十进制转换
    gen = gen + 1;                                      % 代计数器增加
    % 获取每代的最优解及其序号，Y为最优解，I为个体的序号
    [Y, I] = min(ObjV);
    trace(1: N, gen) = X(I, :);                         % 记下每代的最优值
    trace(end, gen) = Y;                                % 记下每代的最优值
end
%% 未优化的神经网络
% value=zeros(1,20);
% for i=1:20
%   value(1,i)=no_optimize_function(input, output, hidden_num, input_test_guiyi, output_test);
% end
% figure 
% plot(1:50,output_test,'r-*',1:50,Y3,'b-o')
% legend('真实值','预测值');
% xlabel('样本序号');
% ylabel('种类');

%% 绘图
figure
plot(1:50,output_test,'r-*',1:50,Y2,'b-o');
legend('真实值','预测值');
xlabel('样本序号');
ylabel('种类');

%% 混淆矩阵
% figure
% cm=confusionchart(output_test,pridiction_output);
% cm.Title='Confusion Matrix Pridiction Data';                   %标题
% cm.ColumnSummary = 'column-normalized';                       %列表示预测百分比
% cm.RowSummary = 'row-normalized';                             %行表示预测百分比